﻿/// Copyright (c) Microsoft Corporation.  All rights reserved.
using System;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
using System.ComponentModel;
using System.Windows.Forms;

namespace Tcvt.Packages
{
    public enum UpdateNotificationsFrequency
    {
        Always = 0,
        Daily,
        Weekly,
        Monthly
    }

    public enum AddShelvesetOptions
    {
        AddExistingShelveset = 0,
        ShelvePendingChanges
    }

    [Guid(GuidList.guidTfsBuggerVSPackageMiscOptionsString)]
    public class MiscOptions : DialogPage
    {
        private const int MAX_CHECKIN_EVALUATION_RESULTS_TO_DISPLAY_CUTOFF = 100;

        private int MaxCheckinEvaluationResultsToDisplayCutoff
        {
            get
            {
                return MAX_CHECKIN_EVALUATION_RESULTS_TO_DISPLAY_CUTOFF;
            }
            set { }
        }

        private DateTime _lastCheckedForUpdates = DateTime.MinValue;
        [Browsable(false)]
        public DateTime LastCheckedForUpdates
        {
            get
            {
                return _lastCheckedForUpdates;
            }
            set
            {
                _lastCheckedForUpdates = value;
            }
        }

        private bool _defaultCheckinOnSuccessBuddyBuild = false;
        [Category("Check-in Settings")]
        [DisplayName("Default Check-in on Successful Buddy Build")]
        [DefaultValue(false)]
        [Description("Indicates the default state of the Check-in on successful Buddy Build checkbox.")]
        public bool DefaultCheckinOnSuccessBuddyBuild
        {
            get
            {
                return _defaultCheckinOnSuccessBuddyBuild;
            }
            set
            {
                _defaultCheckinOnSuccessBuddyBuild = value;
            }
        }

        private bool _defaultDeleteShelvesetsOnSuccessCheckin = false;
        [Category("Check-in Settings")]
        [DisplayName("Default Delete Shelvesets on Successful Check-in")]
        [DefaultValue(false)]
        [Description("Indicates the default state of the Delete shelveset(s) on successful check-in checkbox. " +
            "When set to true, shelvesets associated with a buddy build will be deleted after the build succeeds " +
            "and the corresponding pending changes are successfully checked in.")]
        public bool DefaultDeleteShelvesetsOnSuccessCheckin
        {
            get
            {
                return _defaultDeleteShelvesetsOnSuccessCheckin;
            }
            set
            {
                if (!value || (value && this.DefaultCheckinOnSuccessBuddyBuild))
                {
                    _defaultDeleteShelvesetsOnSuccessCheckin = value;
                }
                else
                {
                    _defaultDeleteShelvesetsOnSuccessCheckin = false;
                    Utils.ShowErrorMessageBox("'Default Check-in on Successful Buddy Build' is false. Please set to true before setting " +
                        "'Default Delete Shelvesets on Successful Check-in' to true.");
                }
            }
        }

        private bool _doNotTriggerCIBuildsOnCheckIn = false;
        [Category("Check-in Settings")]
        [DisplayName("Do Not Trigger CI Builds on Check-in")]
        [DefaultValue(false)]
        [Description("Set to true so that check-ins do not trigger CI builds for buddy build requests " +
            "scheduled against shelvesets. This is equivalent to adding the ***NO_CI*** prefix to the" +
            "shelveset's check-in comments.")]
        public bool DoNotTriggerCIBuildsOnCheckIn
        {
            get
            {
                return _doNotTriggerCIBuildsOnCheckIn;
            }
            set
            {
                _doNotTriggerCIBuildsOnCheckIn = value;
            }
        }

        private bool _defaultUseBuildAgentPooling = false;
        [Category("Build Agent Pooling Settings")]
        [DisplayName("Default Use Build Agent Pooling")]
        [DefaultValue(false)]
        [Description("Indicates the default state of the Use Build Agent Pooling checkbox.")]
        public bool DefaultUseBuildAgentPooling
        {
            get
            {
                return _defaultUseBuildAgentPooling;
            }
            set
            {
                _defaultUseBuildAgentPooling = value;
            }
        }

        private bool _defaultOverrideBuildAgentsPool = false;
        [Category("Build Agent Pooling Settings")]
        [DisplayName("Default Override Build Agents Pool Settings from XML")]
        [DefaultValue(false)]
        [Description("Set to true so that a build agents override file is considered. The file should typically" +
            " reside under the same folder as '$/TeamProjectName/<path-to-TFSBuild.proj>/TFSBuild.proj'. The file" +
            " name should be '<TeamProjectName>_BuildAgents.xml'. A sample file named TeamProject1_BuildAgents.xml" +
            " can be found in this application's installation location.")]
        public bool DefaultOverrideBuildAgentsPool
        {
            get
            {
                return _defaultOverrideBuildAgentsPool;
            }
            set
            {
                if (!value || (value && this.DefaultUseBuildAgentPooling))
                {
                    _defaultOverrideBuildAgentsPool = value;
                }
                else
                {
                    _defaultOverrideBuildAgentsPool = false;
                    Utils.ShowErrorMessageBox("'Default Use Build Agent Pooling' is false. Please set to true before setting " +
                        "'Default Override Build Agents Pool Settings from XML' to true.");
                }
            }
        }

        private bool _useCachedTeamProjectNames = true;
        [Category("Miscellaneous Settings")]
        [DisplayName("Use Cached Team Project Names")]
        [DefaultValue(true)]
        [Description("Set to false so that a fresh copy of the team projects is retrieved from " +
            "the TFS server.")]
        public bool UseCachedTeamProjectNames
        {
            get
            {
                return _useCachedTeamProjectNames;
            }
            set
            {
                _useCachedTeamProjectNames = value;
            }
        }

        private string _buddyBuildWorkItemsTeamProjectName = "";
        [Category("Work Items Settings")]
        [DisplayName("Work Items Project Name")]
        [DefaultValue("")]
        [Description("The Team Project where the buddy build work item type is installed. " +
            "New buddy build work items will be created in that project to track queued buddy builds.")]
        public string BuddyBuildWorkItemsTeamProjectName
        {
            get
            {
                return _buddyBuildWorkItemsTeamProjectName;
            }
            set
            {
                _buddyBuildWorkItemsTeamProjectName = value;
            }
        }

        private bool _createBuddyBuildWorkItems = false;
        [Category("Work Items Settings")]
        [DisplayName("Create Buddy Build Work Items")]
        [DefaultValue(false)]
        [Description("When set to true, a buddy build work item will be created for each buddy build that is queued. " +
            "The setting is ignored if no value is provided for the Work Items Project Name setting.")]
        public bool CreateBuddyBuildWorkItems
        {
            get
            {
                return _createBuddyBuildWorkItems;
            }
            set
            {
                if (!value || (value && this.BuddyBuildWorkItemsTeamProjectName.Length > 0))
                {
                    _createBuddyBuildWorkItems = value;
                }
                else
                {
                    _createBuddyBuildWorkItems = false;
                    Utils.ShowErrorMessageBox("'Work Items Project Name' is blank. Please enter a value before setting " +
                        "'Create Buddy Build Work Items' to true.");
                }
            }
        }

        private int _maxShelvesetsCountAllowed = 500;
        [Category("Shelveset Settings")]
        [DisplayName("Maximum Shelvesets Displayed")]
        [DefaultValue(500)]
        [Description("The maximum number of shelvesets that the Add Shelvesets dialog will display. " +
            "If a username has more than this value, no shelvesets will be display." +
            "Enter a value of 0 to allow unlimited number of shelvesets.")]
        public int MaxShelvesetsCountAllowed
        {
            get
            {
                return _maxShelvesetsCountAllowed;
            }
            set
            {
                _maxShelvesetsCountAllowed = value;
            }
        }

        private bool _allowMultipleShelvesets = false;
        [Category("Shelveset Settings")]
        [DisplayName("Allow Multiple Shelvesets")]
        [DefaultValue(false)]
        [Description("Set to true to enable selecting more than one shelveset for a " +
            "buddy build. This feature requires that the different shelvesets do not " +
            "contain conflicting changes that cannot be resolved automatically.")]
        public bool AllowMultipleShelvesets
        {
            get
            {
                return _allowMultipleShelvesets;
            }
            set
            {
                _allowMultipleShelvesets = value;
            }
        }

        private bool _enableShelvesetsPrequerying = false;
        [Category("Shelveset Settings")]
        [DisplayName("Enable Shelvesets Prequerying")]
        [DefaultValue(false)]
        [Description("Set to true so that shelvesets for the current user are automatically " +
            "listed when the 'Add Shelveset...' button is clicked. Set to false so that clicking " +
            "'Add Shelveset...' will not display the results until the 'Find' button is clicked. The " +
            "latter option is recommended for users with too many shelvesets that would like to " +
            "query for shelvesets owned by other users and do not want to wait for the search results " +
            "to return before they can select a different user and click 'Find'.")]
        public bool EnableShelvesetsPrequerying
        {
            get
            {
                return _enableShelvesetsPrequerying;
            }
            set
            {
                _enableShelvesetsPrequerying = value;
            }
        }

        private bool _enableCellContentClick = false;
        [Category("Shelveset Settings")]
        [DisplayName("Enable Shelveset One-Click Selection")]
        [DefaultValue(false)]
        [Description("Set to true so that clicking on a shelveset in results grid will cause it to be selected " +
            "and automatically added to the selected shelvsets without having to click the 'Add Selected' button. " +
            "Set it to false to add a selection by first clicking on the grid row and then clicking the " +
            "'Add Selected' button.")]
        public bool EnableCellContentClick
        {
            get
            {
                return _enableCellContentClick;
            }
            set
            {
                _enableCellContentClick = value;
            }
        }

        private bool _createdShelvesetsTriggerCI = true;
        [Category("Shelveset Settings")]
        [DisplayName("Created Shelvesets Trigger CI")]
        [DefaultValue(true)]
        [Description("Set to true so that automatically generated shelvesets will cause Continuous Integration (CI) " +
            "builds to be triggered, if configured. Set to false to override CI builds. This is achieved by prepending " +
            "***NO_CI*** to the shelveset comments.")]
        public bool CreatedShelvesetsTriggerCI
        {
            get
            {
                return _createdShelvesetsTriggerCI;
            }
            set
            {
                _createdShelvesetsTriggerCI = value;
            }
        }

        private bool _overrideCheckinPolicyViolations = false;
        [Category("Check-in Policy Settings")]
        [DisplayName("Override Check-in Policy Violations")]
        [DefaultValue(false)]
        [Description("Set to true to override any unsatisfied check-in policies while creating a shelveset. You will " +
            "need to have the 'Check-in Policies Override Comment' set to a value in order to be able to set this to true. " +
            "Note that it is not recommended to override the check-in policies unless you have a very good reason to deem it " +
            "necessary to do that. Also note that overriding the check-in policies might not be adequate if the tool is " +
            "configured to disable that behavior on the server-side.")]
        public bool OverrideCheckinPolicyViolations
        {
            get
            {
                return _overrideCheckinPolicyViolations;
            }
            set
            {
                if (!value || (value && this.CheckinPoliciesOverrideComment.Length > 0))
                {
                    _overrideCheckinPolicyViolations = value;
                }
                else
                {
                    _overrideCheckinPolicyViolations = false;
                    Utils.ShowErrorMessageBox("'Check-in Policies Override Comment' is blank. Please enter a value before setting " +
                        "'Override Check-in Policy Violations' to true.");
                }
            }
        }

        private string _checkinPoliciesOverrideComment = "Check-in policy violations overriden by the TFS Check-in Validation Tool.";
        [Category("Check-in Policy Settings")]
        [DisplayName("Check-in Policies Override Comment")]
        [DefaultValue("Check-in policy violations overriden by the TFS Check-in Validation Tool.")]
        [Description("Set to the comment that will appear in the changeset information after the pending changes are checked in. " +
            "Note that it is not recommended to override the check-in policies unless you have a very good reason to deem it " +
            "necessary to do that. Also note that overriding the check-in policies might not be adequate if the tool is " +
            "configured to disable that behavior on the server-side.")]
        public string CheckinPoliciesOverrideComment
        {
            get
            {
                return _checkinPoliciesOverrideComment;
            }
            set
            {
                if ( (value.Length == 0 || value.Trim().Length == 0) && this.OverrideCheckinPolicyViolations)
                {
                    Utils.ShowErrorMessageBox("'Override Check-in Policy Violations' is set to true. Please enter a non-blank value " +
                        "or set 'Check-in Policies Override Comment' to false in order to be able to set 'Check-in Policies Override Comment' " +
                        "to an empty string.");
                }
                else
                {
                    _checkinPoliciesOverrideComment = value;
                }
            }
        }

        private bool _stopNonPreservedPendingChangesWarnings = false;
        [Category("Shelveset Settings")]
        [DisplayName("Stop Non-Preserved Pending Changes Warnings")]
        [DefaultValue(false)]
        [Description("Set to true to stop getting a warning dialog whenever you uncheck the 'Preserve pending changes " +
            "locally' checkbox after selecting the 'Shelve my current pending changes for me' radio button. The purpose " +
            "of those warning messages is to make sure you are aware that the local pending changes will be lost after the " +
            "checkbox is unchecked.")]
        public bool StopNonPreservedPendingChangesWarnings
        {
            get
            {
                return _stopNonPreservedPendingChangesWarnings;
            }
            set
            {
                _stopNonPreservedPendingChangesWarnings = value;
            }
        }

        private int _maxCheckinEvaluationResultsToDisplay = 10;
        [Category("Check-in Policy Settings")]
        [DisplayName("Max Check-in Evaluation Results to Display")]
        [DefaultValue(10)]
        [Description("Set this to a number between 1 and 100 to control the number of items displayed for each result type " +
            "(conflicts, policy failures, check-in notes failures, and policy evaluation exceptions)in the Check-in " +
            "Evaluation Report.")]
        public int MaxCheckinEvaluationResultsToDisplay
        {
            get
            {
                return _maxCheckinEvaluationResultsToDisplay;
            }
            set
            {
                if (value <= 0 || value > MAX_CHECKIN_EVALUATION_RESULTS_TO_DISPLAY_CUTOFF)
                {
                    Utils.ShowErrorMessageBox(string.Format("Only values between 1 and {0} are allowed.",
                        MAX_CHECKIN_EVALUATION_RESULTS_TO_DISPLAY_CUTOFF));
                }
                else
                {
                    _maxCheckinEvaluationResultsToDisplay = value;
                }
            }
        }

        private bool _skipCheckinEvaluationUponShelving = false;
        [Category("Check-in Policy Settings")]
        [DisplayName("Skip Check-in Evaluation Upon Shelving")]
        [DefaultValue(false)]
        [Description("Set to true to skip the check-in evaluation step when requesting that a shelveset be created " +
            "on the fly with your workspace pending changes. This is not recommended though, and this option is " +
            "only supplied here for extreme or urgent cases.")]
        public bool SkipCheckinEvaluationUponShelving
        {
            get
            {
                return _skipCheckinEvaluationUponShelving;
            }
            set
            {
                _skipCheckinEvaluationUponShelving = value;
            }
        }

        private bool _evaluatePoliciesOnlyForCheckins = true;
        [Category("Check-in Policy Settings")]
        [DisplayName("Evaluate Policies Only for Check-ins")]
        [DefaultValue(true)]
        [Description("Set to true to perform check-in evaluation against your workspace pending changes only when " + 
            "the 'Check-in shelveset(s) on successful Buddy Build' checkbox is checked, and skip the evaluation otherwise. "+
            "Set to false the alwasy evaluate the policies, even for non-check-in buddy builds. The default is true. " +
            "Note that this setting is ignored if the 'Skip Check-in Evaluation Upon Shelving' setting is true.")]
        public bool EvaluatePoliciesOnlyForCheckins
        {
            get
            {
                return _evaluatePoliciesOnlyForCheckins;
            }
            set
            {
                _evaluatePoliciesOnlyForCheckins = value;
            }
        }

        private bool _skipPendingChangesSelection = false;
        [Category("Shelveset Settings")]
        [DisplayName("Skip Pending Changes Selection")]
        [DefaultValue(false)]
        [Description("Set to true to skip the 'Select Pending Changes' dialog that allows you to select a subset of " +
            "the pending changes found in your workspace. When set to true, all pending changes in your workspace " +
            "are shelved.")]
        public bool SkipPendingChangesSelection
        {
            get
            {
                return _skipPendingChangesSelection;
            }
            set
            {
                _skipPendingChangesSelection = value;
            }
        }

        private AddShelvesetOptions _addShelvesetsDefaultSetting = AddShelvesetOptions.AddExistingShelveset;
        [Category("Shelveset Settings")]
        [DisplayName("'Add Shelvesets' Default Setting")]
        [DefaultValue(AddShelvesetOptions.AddExistingShelveset)]
        [Description("Select a setting to control which radio button is selected by default " +
            "under the 'Add Shelvesets' group box. Select 'AddExistingShelveset' to have the " +
            "'Add existing shelvesets' radio button be selected by default or 'ShelvePendingChanges' to have the " +
            "'Shelve my current pending changes for me' radio button be the default selection.")]
        public AddShelvesetOptions AddShelvesetsDefaultSetting
        {
            get
            {
                return _addShelvesetsDefaultSetting;
            }
            set
            {
                _addShelvesetsDefaultSetting = value;
            }
        }

        private string _noCICheckinComment = "***NO_CI***";
        [Category("Shelveset Settings")]
        [DisplayName("'No CI' Check-in Comment")]
        [DefaultValue("***NO_CI***")]
        [Description("Set to a string the represents the 'No CI' comment on TFS. By default, this is '***NO_CI***'. " +
            "But, if this has been changed by overriding the 'NoCICheckinComment' MSBuild property from within your " +
            "TFSBuild.proj or TFSBuild.rsp files, then you can copy that value into this setting. If you set this to " +
            "an empty string, the internal value of '***NO_CI***' will be used.")]
        public string NoCICheckinComment
        {
            get
            {
                return _noCICheckinComment;
            }
            set
            {
                _noCICheckinComment = value;
            }
        }

        private bool _automaticallyCheckForUpdates = false;
        [Category("Software Updates")]
        [DisplayName("Automatically Check for Updates")]
        [DefaultValue(false)]
        [Description("Set to true to check for updates automatically every time you launch the add-in in Visual Studio. " +
            "Set to false if you want to check for updates by choosing the 'Check for Updates' option on the BuddyBuild " +
            "menu.")]
        public bool AutomaticallyCheckForUpdates
        {
            get
            {
                return _automaticallyCheckForUpdates;
            }
            set
            {
                _automaticallyCheckForUpdates = value;
            }
        }

        private UpdateNotificationsFrequency _frequencyOfUpdateNotifications = UpdateNotificationsFrequency.Always;
        [Category("Software Updates")]
        [DisplayName("Frequency of Update Notifications")]
        [DefaultValue(UpdateNotificationsFrequency.Always)]
        [Description("Set to one of the following values (Always, Daily, Weekly, Monthly) to control the frequency of popping up notifications " +
            "for available updates. This value will only be relevant if the 'Automatically Check for Updates' " +
            "setting is checked. Always, the default, specifies that the check for updates is done every time the " +
            "'Queue a Check-in Validation Build' dialog is launched.")]
        public UpdateNotificationsFrequency FrequencyOfUpdateNotifications
        {
            get
            {
                return _frequencyOfUpdateNotifications;
            }
            set
            {
                _frequencyOfUpdateNotifications = value;
            }
        }

        private bool _showAlertsUponCustomSettingsFailure = false;
        [Category("Custom MSBuild Properties Settings")]
        [DisplayName("Show Alerts Upon Failure to Retrieve Custom Settings")]
        [DefaultValue(false)]
        [Description("Set to true to so that message alerts are displayed when the add-in is " +
            "configured to use the web service and the web service fails to return back any " +
            "custom MSBuild properties. Those failures typically indicate that the web service " +
            "installed is an older version that does not support returning custom properties " +
            "or that the web service URI is incorrect.")]
        public bool ShowAlertsUponCustomSettingsFailure
        {
            get
            {
                return _showAlertsUponCustomSettingsFailure;
            }
            set
            {
                _showAlertsUponCustomSettingsFailure = value;
            }
        }

        private bool _supressCustomPropertyWarnings = false;
        [Category("Custom MSBuild Properties Settings")]
        [DisplayName("Supress Custom Property Warnings")]
        [DefaultValue(false)]
        [Description("Set to true to supress messages alerting you about the Buddy Build Integration web service " +
            "not supporting Custom Properties. This usually indicates that an older version of the web service is " +
            "installed and needs to be upgraded to the latest version in order to support configuring Custom MSBuild " + 
            "Properties. Set it to true if you do not need custom propeties support or plan to upgrade the web service " +
            "later.")]
        public bool SupressCustomPropertyWarnings
        {
            get
            {
                return _supressCustomPropertyWarnings;
            }
            set
            {
                _supressCustomPropertyWarnings = value;
            }
        }

        private bool _minimizeTFSHostGroupBoxOnStartup = false;
        [Category("Dialog Space Saving Options")]
        [DisplayName("Minimize TFS Host Group Box on Startup")]
        [DefaultValue(false)]
        [Description("Set to true to have the TFS Host group box minimized when the Buddy Build form is launched. " +
            "You can restore the group box by double-clicking on the label.")]
        public bool MinimizeTFSHostGroupBoxOnStartup
        {
            get
            {
                return _minimizeTFSHostGroupBoxOnStartup;
            }
            set
            {
                _minimizeTFSHostGroupBoxOnStartup = value;
            }
        }

        private bool _minimizeAddShelvesetsGroupBoxOnStartup = false;
        [Category("Dialog Space Saving Options")]
        [DisplayName("Minimize Add Shelvesets Group Box on Startup")]
        [DefaultValue(false)]
        [Description("Set to true to have the Add Shelvesets group box minimized when the Buddy Build form is launched. " +
            "You can restore the group box by double-clicking on the label.")]
        public bool MinimizeAddShelvesetsGroupBoxOnStartup
        {
            get
            {
                return _minimizeAddShelvesetsGroupBoxOnStartup;
            }
            set
            {
                _minimizeAddShelvesetsGroupBoxOnStartup = value;
            }
        }

        private bool _minimizeBuildDefinitionGroupBoxOnStartup = false;
        [Category("Dialog Space Saving Options")]
        [DisplayName("Minimize Build Definition Group Box on Startup")]
        [DefaultValue(false)]
        [Description("Set to true to have the Build Definition group box minimized when the Buddy Build form is launched. " +
            "You can restore the group box by double-clicking on the label.")]
        public bool MinimizeBuildDefinitionGroupBoxOnStartup
        {
            get
            {
                return _minimizeBuildDefinitionGroupBoxOnStartup;
            }
            set
            {
                _minimizeBuildDefinitionGroupBoxOnStartup = value;
            }
        }

        private bool _minimizeOptionsGroupBoxOnStartup = false;
        [Category("Dialog Space Saving Options")]
        [DisplayName("Minimize Options Group Box on Startup")]
        [DefaultValue(false)]
        [Description("Set to true to have the Options group box minimized when the Buddy Build form is launched. " +
            "You can restore the group box by double-clicking on the label.")]
        public bool MinimizeOptionsGroupBoxOnStartup
        {
            get
            {
                return _minimizeOptionsGroupBoxOnStartup;
            }
            set
            {
                _minimizeOptionsGroupBoxOnStartup = value;
            }
        }

        // TODO: For future use.
        //private int _maximumTimeoutForUpdatesRequest = 0;
        //[Category("Software Updates")]
        //[DisplayName("Maximum Timeout for Updates Request")]
        //[DefaultValue(0)]
        //[Description("Set this to the number of milliseconds to be set as the timeout for the web request initiated " +
        //    "for checking for software updates. Set to 0 to use the default timeout value.")]
        //public int MaximumTimeoutForUpdatesRequest
        //{
        //    get
        //    {
        //        return _maximumTimeoutForUpdatesRequest;
        //    }
        //    set
        //    {
        //        if (value < 0)
        //        {
        //            Utils.ShowErrorMessageBox("The value must be greater or equal to zero.");
        //        }
        //        else
        //            _maximumTimeoutForUpdatesRequest = value;
        //    }
        //}
    }
}
